﻿using System;
using ML.Entity;
using ML.IBusiness;
using ML.IRepository;
using System.Linq;
using System.Collections.Generic;
using System.Web.Configuration;
using ML.Utils;

namespace ML.Business
{
    /// <summary>
    /// 订单业务实现类
    /// </summary>
    public class OrderBusiness : IOrderBusiness
    {
        private readonly IOrderRepository orderRepository;
        private readonly IOrderDetailsRepository orderDetailsRepository;
        private readonly IProductRepository productRepository;
        private readonly ICurrencyRepository currencyRepository;
        private readonly IMerchantRepository merchantRepository;
        private readonly ILogger logger = new NLogLogger();

        public OrderBusiness(IOrderRepository _orderRepository, IOrderDetailsRepository _orderDetailsRepository,
            IProductRepository _productRepository, ICurrencyRepository _currencyRepository, IMerchantRepository _merchantRepository)
        {
            orderRepository = _orderRepository;
            orderDetailsRepository = _orderDetailsRepository;
            productRepository = _productRepository;
            currencyRepository = _currencyRepository;
            merchantRepository = _merchantRepository;
        }

        public BaseResult<Pager<OrderResponse>> List(OrderSearch orderSearch)
        {
            //根据传递的条件查询
            Pager<OrderResponse> data = orderRepository.List(orderSearch);
            foreach (var row in data.rows)
            {
                row.StateName = "订单-" + PublicEnumHelper.GetEnumDesc(typeof(OrderStatus), row.State);
            }
            return new BaseResult<Pager<OrderResponse>>(200, data);
        }

        public BaseResult<OrderResponse> GetById(string id)
        {
            var data = orderRepository.GetInfoById(id);
            return new BaseResult<OrderResponse>(200, data);
        }

        public BaseResult<OrderResponse> GetDetailById(string id)
        {
            //根据订单Id查询订单详情信息
            if (!string.IsNullOrEmpty(id))
            {
                var orderInfo = orderRepository.GetDetailById(id);
                orderInfo.StateName = "订单-" + PublicEnumHelper.GetEnumDesc(typeof(OrderStatus), orderInfo.State);
                orderInfo.AnticipationTime = orderInfo.ServiceTime.ToString("HH:mm");

                //查询订单详情
                var orderDetatil = orderDetailsRepository.GetDetailById(id);
                if (orderDetatil.Count() > 0)
                {
                    orderInfo.orderDetail = orderDetatil;
                }
                return new BaseResult<OrderResponse>(200, orderInfo);
            }
            return new BaseResult<OrderResponse>(201);
        }

        public BaseResult<IEnumerable<OrderResponse>> GetListByUserId(string id)
        {
            //根据用户Id查询订单主表信息关联商户列表信息
            var orders = orderRepository.GetListByUserId(id);
            if (orders.Count() <= 0)
            {
                return new BaseResult<IEnumerable<OrderResponse>>(200, null);
            }

            //将订单主表Id组合成数组，并且根据订单主表Id查询订单子表信息
            List<string> orderIds = new List<string>();
            foreach (var order in orders)
            {
                orderIds.Add(order.Id);
            }
            IEnumerable<OrderDetailResponse> orderDetails = orderDetailsRepository.GetOrderDetailIds(orderIds);

            //处理数据
            List<OrderResponse> result = new List<OrderResponse>();
            foreach (var order in orders)
            {
                OrderResponse orderResponse = order;
                orderResponse.StateName = "订单-" + PublicEnumHelper.GetEnumDesc(typeof(OrderStatus), order.State);
                orderResponse.orderDetail = returnOrderDetail(order.Id, orderDetails);
                result.Add(orderResponse);
            }
            return new BaseResult<IEnumerable<OrderResponse>>(200, result);
        }

        private List<OrderDetailResponse> returnOrderDetail(string orderId, IEnumerable<OrderDetailResponse> orderDetailResponse)
        {
            List<OrderDetailResponse> list = new List<OrderDetailResponse>();
            foreach (var orderDetail in orderDetailResponse)
            {
                if (orderDetail.OrderId == orderId)
                {
                    list.Add(orderDetail);
                }
            }
            return list;
        }

        public BaseResult<string> Add(CartOrders cartOrders)
        {
            bool isTrue = false;
            //定义主表实体
            OrderEntity orderEntity = new OrderEntity();
            try
            {
                //组装订单子表集合信息(循环查询产品单价进行赋值)
                decimal price = 0;
                List<OrderDetailsEntity> orderDetails = new List<OrderDetailsEntity>();
                foreach (var orderDetail in cartOrders.Data)
                {
                    orderDetail.OrderId = orderEntity.Id;
                    orderDetail.ProductId = orderDetail.ProductId;
                    decimal productPrice = productRepository.GetDiscountPriceByProductId(orderDetail.ProductId);
                    orderDetail.ProductPrice = productPrice;

                    //汇总总价格
                    price += productPrice * orderDetail.ProductNumber;

                    orderDetails.Add(orderDetail);
                }

                //总价为订单总价格+配送费
                var distributionFee = merchantRepository.GetInfoById(cartOrders.MerchantId).DistributionFee;
                decimal actPayPrice = price + distributionFee;

                //给主表信息赋值
                orderEntity.UserId = cartOrders.UserId;
                orderEntity.MerchantId = cartOrders.MerchantId;

                //订单总额=订单总价格
                orderEntity.Price = price;
                orderEntity.DiscountPrice = 0;

                //实际支付金额=商品总金额+配送费-优惠金额（红包、余额等等）
                orderEntity.ActPayPrice = actPayPrice - orderEntity.DiscountPrice;

                //实际支付人民币，传递实际支付的泰铢转换成人民币
                orderEntity.ActPayRMB = ReturnAcpayRMB(actPayPrice);

                orderEntity.ServiceTime = orderEntity.CreateTime.AddHours(-1).AddMinutes(35);//由于泰国跟我们国家时间有时差，所以需要减去1小时
                orderEntity.OrderNumber = CommonUtil.ReadDateTime() + CommonUtil.LiterNumberReadRandom();

                //添加订单主表和子表信息(使用事务实现)
                isTrue = orderRepository.Add(orderEntity, orderDetails);
            }
            catch (Exception ex)
            {
                logger.Debug(ex.Message);
                return new BaseResult<string>(202, "");
            }
            if (isTrue)
            {
                return new BaseResult<string>(200, orderEntity.Id);
            }
            return new BaseResult<string>(202, "");
        }

        public BaseResult<bool> Update(OrderEntity entity, CartOrders cartOrder)
        {
            //修改收货地址、用餐人数和备注
            entity.ReceivingAddressId = cartOrder.ReceivingAddressId;
            entity.NumberOfMeals = cartOrder.NumberOfMeals;
            entity.Description = cartOrder.Description;
            bool isTrue = orderRepository.Update(entity);
            if (isTrue)
            {
                return new BaseResult<bool>(200, true);
            }
            return new BaseResult<bool>(202, false);
        }

        public BaseResult<bool> UpdateState(string Id, int State)
        {
            //(1:接单,2:商家取消,3:已完成，4:客户取消)
            int state = 0;
            switch (State)
            {
                case 1:
                    state = (int)OrderStatus.processed;
                    break;
                case 2:
                    state = (int)OrderStatus.merchantcancel;
                    break;
                case 3:
                    state = (int)OrderStatus.finish;
                    break;
                case 4:
                    state = (int)OrderStatus.usercancel;
                    break;
            }

            bool isTrue = orderRepository.UpdateState(Id, state);
            if (isTrue)
            {
                return new BaseResult<bool>(200, true);
            }
            return new BaseResult<bool>(202, false);
        }

        public BaseResult<bool> UpdatePayState(string id, int payState)
        {
            var isTrue = orderRepository.UpdatePayState(id, payState);
            if (isTrue)
            {
                return new BaseResult<bool>(200, true);
            }
            return new BaseResult<bool>(202, false);
        }

        public BaseResult<List<int>> GetPaidOrderForWeek(string id)
        {
            var list = new List<int>();
            var baseTime = DateTime.Now.Date;
            for (int i = 0; i < 7; i++)
            {
                var beginTime = baseTime.AddDays(-i);
                var endTime = baseTime.AddDays(-i + 1);
                list.Add(orderRepository.GetPaidOrderByTime(id, beginTime, endTime));
            }
            return new BaseResult<List<int>>(200, list);
        }

        public BaseResult<OrderStatisticsResponse> GetOrderStatistics(string id, string type)
        {
            var orderStatisticsResponse = new OrderStatisticsResponse();
            var baseTime = DateTime.Now;
            switch (type)
            {
                case "TODAY":
                    var beginTime = baseTime.Date;
                    var endTime = DateTime.Now.AddDays(1).Date;
                    var orderStatistics = orderRepository.GetOrderStatistics(id, beginTime, endTime);
                    orderStatisticsResponse.Income = orderStatistics.Sum(o => o.ActPayPrice);
                    orderStatisticsResponse.PaymentOrder = orderStatistics.Count();
                    orderStatisticsResponse.CancelOrder = orderStatistics.Count(o => o.State == 4 || o.State == 5 || o.State == 6);
                    orderStatisticsResponse.PaymentGoods = orderStatistics.Count(o => o.State == 3);
                    break;
                case "MONTH":
                    var startMonth = baseTime.AddDays(1 - baseTime.Day);
                    var endMonth = baseTime.AddMonths(1).AddDays(-1);
                    var orderStatistics2 = orderRepository.GetOrderStatistics(id, startMonth, endMonth);
                    orderStatisticsResponse.Income = orderStatistics2.Sum(o => o.ActPayPrice);
                    orderStatisticsResponse.PaymentOrder = orderStatistics2.Count();
                    orderStatisticsResponse.CancelOrder = orderStatistics2.Count(o => o.State == 4 || o.State == 5 || o.State == 6);
                    orderStatisticsResponse.PaymentGoods = orderStatistics2.Count(o => o.State == 3);
                    break;
            }
            return new BaseResult<OrderStatisticsResponse>(200, orderStatisticsResponse);
        }

        public BaseResult<OrderStatusCountResponse> GetTodayOrderStatus(string id)
        {
            var orderStatisticsResponse = new OrderStatusCountResponse();
            var baseTime = DateTime.Now;

            var beginTime = baseTime.Date;
            var endTime = DateTime.Now.AddDays(1).Date;
            var orderStatistics = orderRepository.GetOrderStatistics(id, beginTime, endTime);
            orderStatisticsResponse.WaitingForDelivery = orderStatistics.Count(o => o.State == 2);
            orderStatisticsResponse.WaitingForOrder = orderStatistics.Count(o => o.State == 0);
            orderStatisticsResponse.WaitingForShipping = orderStatistics.Count(o => o.State == 1);
            return new BaseResult<OrderStatusCountResponse>(200, orderStatisticsResponse);
        }

        /// <summary>
        /// 将泰铢处理成人民币存放
        /// </summary>
        /// <param name="actPayPrice">泰铢的总金额</param>
        /// <returns></returns>
        private decimal ReturnAcpayRMB(decimal actPayPrice)
        {
            //公式:泰铢÷（汇率-浮动汇率），转换之后保留2位小数
            decimal buyCurrency = 0.00m;
            var huilv = currencyRepository.GetLastOne();
            if (huilv == null)
            {
                buyCurrency = ConfigHelper.DefaultHuiLv;
            }
            else
            {
                buyCurrency = huilv.BuyCurrency;
            }
            var result = actPayPrice / (buyCurrency - ConfigHelper.FuDongHuiLv);
            return Math.Round(result, 2);
        }
    }
}